#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :fn_clear_waster_record.py
# @Time      :2024/11/12 22:12
# @Author    :zhou_yi

import asyncio
from datetime import datetime
import random

from tools.units import DATETIME, CHART, FILE, Path
from models.ClearWasterRecords import CWRSRecord, CWRSPoint, CWRSummary, OutCWRS, InputCWRS
from service.fn_db import addressDB, clearWasterRecordsDB
from settings import Root


class _CWRS:
    def __init__(self, In: InputCWRS):
        self.point_name = In.point
        self.start = In.start
        self.end = In.end
        self.timeframe: list[tuple[int]] = DATETIME.get_month_range(self.start, self.end)  # 时间范围年月列表

    @property  # 点位数据
    async def point(self) -> CWRSPoint:
        res = await addressDB.fetch_by_point(self.point_name)
        return CWRSPoint(**res)

    @property  # 数据库的记录
    async def records(self) -> list[CWRSRecord]:
        get_fk = await self.point
        recorders: list = await clearWasterRecordsDB.fetch_by_fk_and_timeframe(get_fk.id, self.start, self.end)

        res = []
        for r in recorders:
            r.update({
                'date': datetime.strftime(r['datetime'], '%Y/%m/%d'),  # 增加日期
                'time': datetime.strftime(r['datetime'], '%H:%M')  # 增加时间
            })
            res.append(CWRSRecord(**r))

        return res

    @property  # 求真实记录中年月列表
    async def year_and_month_tuple(self) -> list[tuple]:
        _recorders = await self.records
        return [(r.datetime.year, r.datetime.month) for r in _recorders]

    # 单月随机记录 一条记录
    async def rnd_one_month_record(self, year: int, month: int) -> CWRSRecord:
        get_fk = await self.point
        fk: str = get_fk.id

        # 处理datetime 对象
        rnd_dt: datetime = DATETIME.rnd_datetime(year, month)  # datetime.datetime(2024, 1, 1, 17, 21)

        _weight: dict = {f"w{i}": random.randint(10, 20) for i in range(1, 9)}
        _w_total = sum(_weight.values())
        _time: str = rnd_dt.strftime('%H:%M')
        _date: str = rnd_dt.strftime('%Y/%m/%d')

        # 随机重量记录
        _rec = {
            '_id': CHART.uid_key(),
            'fk': fk,
            'datetime': rnd_dt,
            'date': _date,
            'time': _time,
            'f_pic': "['图片1', '图片2']",
            'b_pic': "['图片1', '图片2']",
            'w_total': _w_total,
            'is_really': 0
        }
        _rec.update(_weight)  # 增加8个分类项

        return CWRSRecord(**_rec)

    # 时间范围内生成随机记录
    async def rnd_recorders(self):
        _lst = []
        r_time_lst = await self.year_and_month_tuple  # 真实存在的数据 时间元组

        if r_time_lst:

            for time_tup in self.timeframe:
                if time_tup not in r_time_lst:
                    _year, _month = time_tup[0], time_tup[1]
                    _rnd: CWRSRecord = await self.rnd_one_month_record(year=_year, month=_month)
                    _lst.append(_rnd)

        else:
            for time_tup in self.timeframe:
                _year, _month = time_tup[0], time_tup[1]
                _rnd: CWRSRecord = await self.rnd_one_month_record(year=_year, month=_month)
                _lst.append(_rnd)

        return _lst

    # 真假记录合并
    async def merge_real_and_rnd(self):
        real = await self.records
        rnd = await self.rnd_recorders()
        merge = real + rnd

        # 排序
        merge = sorted(merge, key=lambda itm: datetime.strftime(itm.datetime, '%Y-%m-%d %H:%M'))
        return merge

    @staticmethod
    def get_summary_and_total(records: list[CWRSRecord]) -> tuple[list[CWRSummary], int]:
        summary = [{'idx': idx, 'date': r.date, 'time': r.time, 'w_total': r.w_total, 'is_really': r.is_really} for
                   idx, r in enumerate(records, 1)]
        summary = list(map(lambda x: CWRSummary(**x), summary))
        total: int = sum([itm.w_total for itm in summary])
        return summary, total

    async def context_really(self):
        point = await self.point
        records = await self.records
        summary, total = self.get_summary_and_total(records)
        json_dic = point.dict()
        json_dic.update({

            'records': records,
            'summary': summary,
            'total': total
        })
        return OutCWRS(**json_dic)

    async def context_merge(self):
        point = await self.point
        records = await self.merge_real_and_rnd()
        summary, total = self.get_summary_and_total(records)
        json_dic = point.dict()
        json_dic.update({

            'records': records,
            'summary': summary,
            'total': total
        })
        return OutCWRS(**json_dic)


async def file_clear_waster_records(In: InputCWRS):
    _cwrs = _CWRS(In)
    filename = Path(Root) / f"tmp/{CHART.uid_key()}.docx"

    context = await _cwrs.context_really() if In.really else await _cwrs.context_merge()

    res = FILE.word_file(In.tpl, context.dict(), filename.__str__())
    download_name = f"记录_垃圾清运_{In.point}.docx"
    return res, download_name


async def io_clear_waster_records(In: InputCWRS):
    _cwrs = _CWRS(In)
    context = await _cwrs.context_really() if In.really else await _cwrs.context_merge()
    io_ = FILE.word_Io(In.tpl, context.dict())
    download_name = f"记录_垃圾清运_{In.point}.docx"
    return io_, download_name


if __name__ == '__main__':
    _dic = {
        'tpl': r'E:\py_code\prj_6\tpl\模板_记录_无图_有害垃圾清运.docx',
        'point': '顺商鑫海韵通西单商场',
        'start': '2024-11-01',
        'end': '2025-07-31',
        'really': False
    }

    _In = InputCWRS(**_dic)
    cwrs = _CWRS(_In)
    x = asyncio.run(file_clear_waster_records(_In))
    print(x)
